<?php

/**
 * Zen_Validate_NoDbRecordExists
 * 
 * Проверка отсутствия записи в таблице
 * 
 * @author Александр Махомет aka San для http://zendframework.ru
 * 
 */
class Zen_Validate_NoNeighbourRecordExists extends Zend_Validate_Abstract 
{
    /**
     * Метка ошибки
     * @var const 
     */    
    const NEIGHBOUR_EXISTS = 'neighbourRecordExists';
    
    /**
     * Текст ошибки
     * @var array 
     */
    protected $_messageTemplates = array(
        self::NEIGHBOUR_EXISTS => 'Neighbour with value %value% already exists in tree'
    );

    /**
     * Имя таблица в которой будет происходить поиск записи
     * @var string
     */    
    protected $_model = null;    
    
    /**
     * Элемент формы по которому будет происходить поиск значения 
     * @var string
     */    
    protected $_form_element = null;    

   	/**
     * Тип материала дерева 
     * @var string
     */    
    protected $_type = null;
    
    /**
     * Используемый адаптер базы данных
     *
     * @var unknown_type
     */    
    protected $_adapter = null;    

    /**
     * Имя поля по которому будет происходить поиск значения 
     * @var string
     */    
    protected $_field = null; 
    
    /**
     * Конструктор
     * 
     * @param string $table Имя таблицы
     * @param string $field Имя поля
     * @param Zend_Db_Adapter_Abstract $adapter Адаптер базы данных
     */
    public function __construct($model, $type, $form_element, $params, $adapter = null)
    {
        $this->_model = $model;
        $this->_form_element = $form_element;
        $this->_params = $params;
        $this->_type = $type;
        
        if ($adapter == null) {
        	// Если адаптер не задан, пробуем подключить адаптер заданный по умолчанию для Zend_Db_Table
        	$adapter = Zend_Db_Table::getDefaultAdapter();
        	
        	// Если адаптер по умолчанию не задан выбрасываем исключение
        	if ($adapter == null) {
        	   throw new Exception('No user and no default adapter was found');
        	}
        }
        
        $this->_adapter = $adapter;
    }
    
	private function _isValid($value) {
		$this->_setValue($value);
		$adapter = $this->_adapter;
		$model = $this->_model;
		$type = $this->_type;
        $form_element = $this->_form_element;
        $params = $this->_params;
        $field = $form_element->getName();
        $this->_field = $field;

        if (!$form_element->isRequired() && !$value) return true;
        
        //Проверяем случай обновления
        if ( isset($params['id']) ) {
        	$id = $params['id'];
        	$this_item = $model
        				->select()
        				->setColumns(array('tree'=>array('parent_id'),$type=>array($field)))
        				->getOne("tree.id=$id");
        	if (! $this_item) throw new Exception('Error! There is no item given.');
        	$res = $model
        				->select()
        				->setParentId($this_item['parent_id'])
        				->setColumns(array($type=>array('id',$field)))
        				->getData("$field='$value'");
        	if (! $res) return true;
        	if ( count($res) > 1 ) return false;
        	if ( $res[0]['id'] != $id )  return false;
        	return true;
        }
		//Проверяем случай добавления
        if ( isset($params['parent_id']) ) {
        	$parent_id = $params['parent_id'];
        	$res = $model
        				->select()
        				->setColumns(array('tree'=>array('id','parent_id'),$type=>array($field)))
        				->getOne("parent_id=$parent_id and $field='$value'");
        	if (! $res ) return true;
        }
        return false;
	}
	
	public function isValid($value) {
		$res = $this->_isValid($value);
		if (! $res) {
			$this->_error(self::NEIGHBOUR_EXISTS,$value);
			return false;	
		}
		else return true; 
	}
	
}

